home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / misc / 39 / do1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-07-17  |  6.7 KB  |  254 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2. /* do.c - version 1.0.3 */
  3.  
  4. /* Contains code for 'd', 'D' (drop), '>', '<' (up, down) and 't' (throw) */
  5.  
  6. #include "hack.h"
  7.  
  8. extern struct obj *splitobj(), *addinv();
  9. extern boolean hmon();
  10. extern boolean level_exists[];
  11. extern struct monst youmonst;
  12. extern char *Doname2();
  13. extern char *nomovemsg;
  14.  
  15. struct monst *bhit(), *boomhit();
  16. dothrow()
  17. {
  18.     register struct obj *obj;
  19.     register struct monst *mon;
  20.     register tmp;
  21.  
  22.     obj = getobj("#)", "throw");   /* it is also possible to throw food */
  23.                        /* (or jewels, or iron balls ... ) */
  24.     if(!obj || !getdir(1))           /* ask "in what direction?" */
  25.         return(0);
  26.     if(obj->owornmask & (W_ARMOR | W_RING)){
  27.         pline("You can't throw something you are wearing.");
  28.         return(0);
  29.     }
  30.  
  31.     u_wipe_engr(2);
  32.  
  33.     if(obj == uwep){
  34.         if(obj->cursed){
  35.             pline("Your weapon is welded to your hand.");
  36.             return(1);
  37.         }
  38.         if(obj->quan > 1)
  39.             setuwep(splitobj(obj, 1));
  40.         else
  41.             setuwep((struct obj *) 0);
  42.     }
  43.     else if(obj->quan > 1)
  44.         (void) splitobj(obj, 1);
  45.     freeinv(obj);
  46.     if(u.uswallow) {
  47.         mon = u.ustuck;
  48.         bhitpos.x = mon->mx;
  49.         bhitpos.y = mon->my;
  50.     } else if(u.dz) {
  51.       if(u.dz < 0) {
  52.         pline("%s hits the ceiling, then falls back on top of your head.",
  53.         Doname2(obj));        /* note: obj->quan == 1 */
  54.         if(obj->olet == POTION_SYM)
  55.         potionhit(&youmonst, obj);
  56.         else {
  57.         if(uarmh) pline("Fortunately, you are wearing a helmet!");
  58.         losehp(uarmh ? 1 : rnd((int)(obj->owt)), "falling object");
  59.         dropy(obj);
  60.         }
  61.       } else {
  62.         pline("%s hits the floor.", Doname2(obj));
  63.         if(obj->otyp == EXPENSIVE_CAMERA) {
  64.         pline("It is shattered in a thousand pieces!");
  65.         obfree(obj, Null(obj));
  66.         } else if(obj->otyp == EGG) {
  67.         pline("\"Splash!\"");
  68.         obfree(obj, Null(obj));
  69.         } else if(obj->olet == POTION_SYM) {
  70.         pline("The flask breaks, and you smell a peculiar odor ...");
  71.         potionbreathe(obj);
  72.         obfree(obj, Null(obj));
  73.         } else {
  74.         dropy(obj);
  75.         }
  76.       }
  77.       return(1);
  78.     } else if(obj->otyp == BOOMERANG) {
  79.         mon = boomhit(u.dx, u.dy);
  80.         if(mon == &youmonst) {        /* the thing was caught */
  81.             (void) addinv(obj);
  82.             return(1);
  83.         }
  84.     } else {
  85.         if(obj->otyp == PICK_AXE && shkcatch(obj))
  86.             return(1);
  87.  
  88.         mon = bhit(u.dx, u.dy, (obj->otyp == ICE_BOX) ? 1 :
  89.             (!Punished || obj != uball) ? 8 : !u.ustuck ? 5 : 1,
  90.             obj->olet,
  91.             (int (*)()) 0, (int (*)()) 0, obj);
  92.     }
  93.     if(mon) {
  94.         /* awake monster if sleeping */
  95.         wakeup(mon);
  96.  
  97.         if(obj->olet == WEAPON_SYM) {
  98.             tmp = -1+u.ulevel+mon->data->ac+abon();
  99.             if(obj->otyp < ROCK) {
  100.                 if(!uwep ||
  101.                     uwep->otyp != obj->otyp+(BOW-ARROW))
  102.                     tmp -= 4;
  103.                 else {
  104.                     tmp += uwep->spe;
  105.                 }
  106.             } else
  107.             if(obj->otyp == BOOMERANG) tmp += 4;
  108.             tmp += obj->spe;
  109.             if(u.uswallow || tmp >= rnd(20)) {
  110.                 if(hmon(mon,obj,1) == TRUE){
  111.                   /* mon still alive */
  112. #ifndef NOWORM
  113.                   cutworm(mon,bhitpos.x,bhitpos.y,obj->otyp);
  114. #endif NOWORM
  115.                 } else mon = 0;
  116.                 /* weapons thrown disappear sometimes */
  117.                 if(obj->otyp < BOOMERANG && rn2(3)) {
  118.                     /* check bill; free */
  119.                     obfree(obj, (struct obj *) 0);
  120.                     return(1);
  121.                 }
  122.             } else miss(objects[obj->otyp].oc_name, mon);
  123.         } else if(obj->otyp == HEAVY_IRON_BALL) {
  124.             tmp = -1+u.ulevel+mon->data->ac+abon();
  125.             if(!Punished || obj != uball) tmp += 2;
  126.             if(u.utrap) tmp -= 2;
  127.             if(u.uswallow || tmp >= rnd(20)) {
  128.                 if(hmon(mon,obj,1) == FALSE)
  129.                     mon = 0;    /* he died */
  130.             } else miss("iron ball", mon);
  131.         } else if(obj->olet == POTION_SYM && u.ulevel > rn2(15)) {
  132.             potionhit(mon, obj);
  133.             return(1);
  134.         } else {
  135.             if(cansee(bhitpos.x,bhitpos.y))
  136.                 pline("You miss %s.",mon_nam(mon));
  137.             else pline("You miss it.");
  138.             if(obj->olet == FOOD_SYM && mon->data->mlet == 'd')
  139.                 if(tamedog(mon,obj)) return(1);
  140.             if(obj->olet == GEM_SYM && mon->data->mlet == 'u' &&
  141.                 !mon->mtame){
  142.              if(obj->dknown && objects[obj->otyp].oc_name_known){
  143.               if(objects[obj->otyp].g_val > 0){
  144.                 u.uluck += 5;
  145.                 goto valuable;
  146.               } else {
  147.                 pline("%s is not interested in your junk.",
  148.                 Monnam(mon));
  149.               }
  150.              } else { /* value unknown to @ */
  151.                 u.uluck++;
  152.             valuable:
  153.                 if(u.uluck > LUCKMAX)    /* dan@ut-ngp */
  154.                 u.uluck = LUCKMAX;
  155.                 pline("%s graciously accepts your gift.",
  156.                 Monnam(mon));
  157.                 mpickobj(mon, obj);
  158.                 rloc(mon);
  159.                 return(1);
  160.              }
  161.             }
  162.         }
  163.     }
  164.         /* the code following might become part of dropy() */
  165.     if(obj->otyp == CRYSKNIFE)
  166.         obj->otyp = WORM_TOOTH;
  167.     obj->ox = bhitpos.x;
  168.     obj->oy = bhitpos.y;
  169.     obj->nobj = fobj;
  170.     fobj = obj;
  171.     /* prevent him from throwing articles to the exit and escaping */
  172.     /* subfrombill(obj); */
  173.     stackobj(obj);
  174.     if(Punished && obj == uball &&
  175.         (bhitpos.x != u.ux || bhitpos.y != u.uy)){
  176.         freeobj(uchain);
  177.         unpobj(uchain);
  178.         if(u.utrap){
  179.             if(u.utraptype == TT_PIT)
  180.                 pline("The ball pulls you out of the pit!");
  181.             else {
  182.                 register long side =
  183.                 rn2(3) ? LEFT_SIDE : RIGHT_SIDE;
  184.                 pline("The ball pulls you out of the bear trap.");
  185.                 pline("Your %s leg is severely damaged.",
  186.                 (side == LEFT_SIDE) ? "left" : "right");
  187.                 set_wounded_legs(side, 500+rn2(1000));
  188.                 losehp(2, "thrown ball");
  189.             }
  190.             u.utrap = 0;
  191.         }
  192.         unsee();
  193.         uchain->nobj = fobj;
  194.         fobj = uchain;
  195.         u.ux = uchain->ox = bhitpos.x - u.dx;
  196.         u.uy = uchain->oy = bhitpos.y - u.dy;
  197.         setsee();
  198.         (void) inshop();
  199.     }
  200.     if(cansee(bhitpos.x, bhitpos.y)) prl(bhitpos.x,bhitpos.y);
  201.     return(1);
  202. }
  203.  
  204. /* split obj so that it gets size num */
  205. /* remainder is put in the object structure delivered by this call */
  206. struct obj *
  207. splitobj(obj, num) register struct obj *obj; register int num; {
  208. register struct obj *otmp;
  209.     otmp = newobj(0);
  210.     *otmp = *obj;        /* copies whole structure */
  211.     otmp->o_id = flags.ident++;
  212.     otmp->onamelth = 0;
  213.     obj->quan = num;
  214.     obj->owt = weight(obj);
  215.     otmp->quan -= num;
  216.     otmp->owt = weight(otmp);    /* -= obj->owt ? */
  217.     obj->nobj = otmp;
  218.     if(obj->unpaid) splitbill(obj,otmp);
  219.     return(otmp);
  220. }
  221.  
  222. more_experienced(exp,rexp)
  223. register int exp, rexp;
  224. {
  225.     extern char pl_character[];
  226.  
  227.     u.uexp += exp;
  228.     u.urexp += 4*exp + rexp;
  229.     if(exp) flags.botl = 1;
  230.     if(u.urexp >= ((pl_character[0] == 'W') ? 1000 : 2000))
  231.         flags.beginner = 0;
  232. }
  233.  
  234. set_wounded_legs(side, timex)
  235. register long side;
  236. register int timex;
  237. {
  238.     if(!Wounded_legs || (Wounded_legs & TIMEOUT))
  239.         Wounded_legs |= side + timex;
  240.     else
  241.         Wounded_legs |= side;
  242. }
  243.  
  244. heal_legs()
  245. {
  246.     if(Wounded_legs) {
  247.         if((Wounded_legs & BOTH_SIDES) == BOTH_SIDES)
  248.             pline("Your legs feel somewhat better.");
  249.         else
  250.             pline("Your leg feels somewhat better.");
  251.         Wounded_legs = 0;
  252.     }
  253. }
  254.